import dearpygui.dearpygui as dpg
from threading import Thread
import time
from PID import Pid

dpg.create_context()

# settings
samplerate_time = 0.05
adjustment_range = 500
plot_size_x = 100
auto_fit = True
run = True

# create deault data
input_val = 0
datax = list(float(i) / 10 for i in range(plot_size_x))
data_pid_y = [0] * plot_size_x
data_setVal_y = [0] * plot_size_x


def update_data():
    global pid, datax, data_pid_y, data_setVal_y, auto_fit, input_val
    pid = Pid(0, 0, 0, dt=1 / samplerate_time)
    while True:
        if run:
            pid.exp_val = input_val
            pid.KP = dpg.get_value("Kp")
            pid.KI = dpg.get_value("Ki")
            pid.KD = dpg.get_value("Kd")
            # update data
            data_pid_y.pop(0)
            data_pid_y.append(pid.calculate())
            data_setVal_y.pop(0)
            data_setVal_y.append(input_val)
            dpg.set_value("series_setVal", [datax, data_setVal_y])
            dpg.set_value("series_pid", [datax, data_pid_y])
        if auto_fit:
            dpg.fit_axis_data("x_axis")
            dpg.fit_axis_data("y_axis")
            dpg.set_axis_limits("x_axis", 0, float(plot_size_x / 10))
            dpg.set_axis_limits("y_axis", 0, 500)

        time.sleep(samplerate_time)


def reset_config():
    global pid
    dpg.set_value("Kp", 0.04)
    dpg.set_value("Ki", 0.7)
    dpg.set_value("Kd", 0.015)


def set_val():
    global pid, input_val
    input_val = dpg.get_value("Sv")


def set_run(sender):
    global run
    run = dpg.get_value(sender)


def set_auto_fit(sender):
    global auto_fit
    auto_fit = dpg.get_value(sender)
    if not auto_fit:
        dpg.set_axis_limits_auto("x_axis")
        dpg.set_axis_limits_auto("y_axis")


with dpg.window(tag="Primary Window", height=-1):
    with dpg.theme(tag="plot_theme_pid"):
        with dpg.theme_component(dpg.mvLineSeries):
            dpg.add_theme_color(
                dpg.mvPlotCol_Line, (255, 255, 50), category=dpg.mvThemeCat_Plots
            )
            dpg.add_theme_style(
                dpg.mvPlotStyleVar_Marker,
                dpg.mvPlotMarker_Square,
                category=dpg.mvThemeCat_Plots,
            )
            dpg.add_theme_style(
                dpg.mvPlotStyleVar_MarkerSize, 2, category=dpg.mvThemeCat_Plots
            )

    with dpg.theme(tag="plot_theme_setVal"):
        with dpg.theme_component(dpg.mvLineSeries):
            dpg.add_theme_color(
                dpg.mvPlotCol_Line, (0, 180, 255), category=dpg.mvThemeCat_Plots
            )

    with dpg.plot(label="Simulate", height=400, width=-1):
        # optionally create legend
        dpg.add_plot_legend()

        # REQUIRED: create x and y axes
        dpg.add_plot_axis(dpg.mvXAxis, label="x", tag="x_axis")
        dpg.add_plot_axis(dpg.mvYAxis, label="y", tag="y_axis")

        # series belong to a y axis
        dpg.add_line_series(
            datax, data_setVal_y, label="Set Val", parent="y_axis", tag="series_setVal"
        )
        dpg.add_line_series(
            datax, data_pid_y, label="PID Out", parent="y_axis", tag="series_pid"
        )
    dpg.bind_item_theme("series_setVal", "plot_theme_setVal")
    dpg.bind_item_theme("series_pid", "plot_theme_pid")

    with dpg.group(horizontal=True):
        dpg.add_button(label="Reset", tag="Btn_Reset", callback=reset_config)
        dpg.add_checkbox(
            label="Run", tag="Radio_Run", default_value=True, callback=set_run
        )
        dpg.add_checkbox(
            label="Auto Fit",
            tag="Radio_AutoFit",
            default_value=True,
            callback=set_auto_fit,
        )

    with dpg.group(horizontal=True):
        dpg.add_text("Val")
        dpg.add_slider_int(
            tag="Sv",
            default_value=0,
            max_value=adjustment_range,
            width=-1,
            callback=set_val,
        )

    with dpg.group(horizontal=True):
        dpg.add_text("Kp")
        dpg.add_slider_float(
            tag="Kp",
            default_value=0.04,
            min_value=-1,
            max_value=1,
            width=-1,
        )

    with dpg.group(horizontal=True):
        dpg.add_text("Ki")
        dpg.add_slider_float(
            tag="Ki",
            default_value=0.7,
            min_value=-2,
            max_value=2,
            width=-1,
        )

    with dpg.group(horizontal=True):
        dpg.add_text("Kd")
        dpg.add_slider_float(
            tag="Kd",
            default_value=0.015,
            min_value=-2,
            max_value=2,
            width=-1,
        )

Thread(target=update_data, daemon=True).start()

dpg.create_viewport(title="PID Simulate", width=700, height=570)
dpg.setup_dearpygui()
dpg.show_viewport()
dpg.set_primary_window("Primary Window", True)
dpg.start_dearpygui()
dpg.destroy_context()
